查看原文
其他

利用Python统计连续登录N天或以上用户

可以叫我才哥 可以叫我才哥 2021-10-08

在有些时候,我们需要统计连续登录N天或以上用户,这里采用python通过分组排序、分组计数等步骤实现该功能,具体如下:

导入需要的库
import pandas as pd
import numpy as np
第一步,导入数据

原始数据是一份csv文件,我们用pandas的方法read_csv直接读取

df = pd.read_csv(r"C:\Users\Gdc\Documents\登录日志.csv")
#读取登录日志数据

这里的登录日志只有两个字段:@timestamp和rold_id。前者是用户登录的时间,后者是用户的ID,考虑到时间的格式,我们需要做简单处理去掉后面的时间保留日期。

第二步,数据预处理

数据预处理方面我们需要做的工作有三部分

  • 时间只取日期,去掉时间部分

我们使用info方法可以发现,时间字段的格式是object,并非时间格式 

但是我们需要统计的时间单位是以日为周期,故而这里可以先做简单的去掉时间部分的处理方式

采用字符串的split方法,按照‘ ’(空格)进行切片,取第一部分即可

df['@timestamp']=df['@timestamp'].str.split(' ').str[0]

#因为日期数据为时间格式,可以简单使用字符串按照空格切片后取第一部分

  • 删除日志里重复的数据(同一天玩家可以登录多次,故而只需要保留一条即可)

我们看到上面处理过的数据,可以发现role_id为570837202的用户在1月8日存在多条记录,为方便后续计算,这里需要进行去重处理。

采取drop_duplicate方案即可保留删除重复数据只保留一条

df.drop_duplicates(inplace=True)
#因为玩家在某一天存在登录多次情况,这里可以用去重过滤掉多余数据

  • 将时间字段列转化为时间格式

同样也是为了方便后续使用时间加减计算登录行为数,@timestamp字段需要调整为时间日期格式

采取to_datetime方法进行处理

df["@timestamp"] = pd.to_datetime(df["@timestamp"])
#将日期列转化为 时间格式


第三步,分组排序

分组排序是指将每个用户登录日期进行组内排序

采用groupby方法结合rank方法进行处理

df['辅助列'] = df["@timestamp"].groupby(df['role_id']).rank()
#分组排序

第四步,计算差值

这一步是辅助操作,使用第三步中的辅助列与用户登录日期做差值得到一个日期,若某用户某几列该值相同,则代表这几天属于连续登录

因为辅助列是float型,我们在做时间差的时候需要用到to_timedelta且unit='d'用来表示减去的是天数,这样获得的差值就会是一个日期

df['date_sub'] = df['@timestamp'] - pd.to_timedelta(df['辅助列'],unit='d')
#计算登录日期与组内排序的差值(是一个日期)

第五步,分组计数

通过上一步,我们可以知道,计算每个用户date_sub列出现的次数即可算出该用户连续登录的天数

data = df.groupby(['role_id','date_sub']).count().reset_index()
#根据用户id和上一步计算的差值 进行分组计数

自此,我们计算出了每个用户连续登录天数

修改辅助列名称
data = data[['role_id','date_sub','辅助列']].rename(columns={'辅助列':'连续登录天数'})
#修改辅助列名称

第六步,计算每个用户连续登录最大天数

这里用到的是sort_values和first方法,对每个用户连续登录天数做组内排序(降序),再取第一个值即为该用户连续登录最大天数

data = data.sort_values(by='连续登录天数',ascending=False).groupby('role_id').first().reset_index()
#计算每个玩家连续登录最大天数

补充

当我们计算出每个用户在周期内的每个连续登录天数后,想计算连续登录N天或以上玩家清单就非常方便了,条件筛选即可。

同时,也可以自由计算连续登录最大天数 各玩家数等等。

全部代码如下

import pandas as pd
import numpy as np

df = pd.read_csv(r"C:\Users\Gdc\Documents\登录日志.csv")
#读取登录日志数据

df['@timestamp']=df['@timestamp'].str.split(' ').str[0]
#因为日期数据为时间格式,可以简单使用字符串按照空格分列后取第一部分

df.drop_duplicates(inplace=True)
#因为玩家在某一天存在登录多次情况,这里可以用去重过滤掉多余数据

df["@timestamp"] = pd.to_datetime(df["@timestamp"])
#将日期列转化为 时间格式

df['辅助列'] = df["@timestamp"].groupby(df['role_id']).rank()
#分组排序

df['date_sub'] = df['@timestamp'] - pd.to_timedelta(df['辅助列'],unit='d')
#计算登录日期与组内排序的差值(是一个日期)

data = df.groupby(['role_id','date_sub']).count().reset_index()
#根据用户id和上一步计算的差值 进行分组计数

data = data[['role_id','date_sub','辅助列']].rename(columns={'辅助列':'连续登录天数'})
#修改辅助列名称

data = data.sort_values(by='连续登录天数',ascending=False).groupby('role_id').first().reset_index()
#计算每个玩家连续登录最大天数


: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存